package com.cdk8s.example.simplespringboot.utils;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Array;
import java.text.Collator;
import java.util.*;

/**
 * 集合工具类.
 */
public final class CollectionUtil {

	// 不可变长度
	public static <T> List<T> emptyList() {
		return Collections.emptyList();
	}

	// 不可变长度
	public static <T> Set<T> emptySet() {
		return Collections.emptySet();
	}

	// 不可变长度
	public static Collection emptyCollection() {
		return CollectionUtils.EMPTY_COLLECTION;
	}

	// 不可变长度
	public static <K, V> Map<K, V> emptyMap() {
		return Collections.emptyMap();
	}


	/**
	 * 根据首字母正序排序（支持中文、拼音）
	 * 比如有个列表，最终排序完效果是这样：[angel, upupmo李, upupmo张, 安全, 终归]
	 *
	 * @param list
	 * @param <T>  基础类型
	 * @return
	 */
	public static <T> List<T> sortByFirstLetterPositive(List<T> list) {
		Collator collator = Collator.getInstance(Locale.CHINA);
		list.sort((a, b) -> collator.compare(a, b));
		return list;
	}

	/**
	 * 根据首字母倒序排序（支持中文、拼音）
	 * 比如有个列表，最终排序完效果是这样：[终归, 安全, upupmo张, upupmo李, angel]
	 *
	 * @param list
	 * @param <T>  基础类型
	 * @return
	 */
	public static <T> List<T> sortByFirstLetterReverse(List<T> list) {
		Collator collator = Collator.getInstance(Locale.CHINA);
		list.sort((a, b) -> collator.compare(b, a));
		return list;
	}

	// =====================================Apache Common 包 start=====================================


	public static boolean isNotEmpty(final Collection coll) {
		return CollectionUtils.isNotEmpty(coll);
	}

	public static boolean isEmpty(final Collection coll) {
		return CollectionUtils.isEmpty(coll);
	}

	public static boolean isNotEmpty(final Object[] coll) {
		return !ArrayUtils.isEmpty(coll);
	}

	public static boolean isEmpty(final Object[] coll) {
		return ArrayUtils.isEmpty(coll);
	}


	public static boolean isNotEmpty(Map<?, ?> map) {
		return !isEmpty(map);
	}

	public static boolean isEmpty(Map<?, ?> map) {
		return MapUtils.isEmpty(map);
	}

	public static <T> T[] addAll(final T[] array1, final T... array2) {
		return ArrayUtils.addAll(array1, array2);
	}

	/**
	 * 把字符串转换成 list
	 */
	public static List<String> stringToList(String str, String separator) {
		String[] split = StringUtils.split(str, separator);
		return toList(split);
	}

	// =====================================Apache Common 包 end=====================================

	// =====================================Guava 包 end=====================================

	/**
	 * 把一个 list 拆分成多个子 list（使用 guava）
	 */
	public static <T> List<List<T>> partitionList(List<T> list, int groupSize) {
		return Lists.partition(list, groupSize);
	}

	/**
	 * 对 list 进行反向操作（也就是把集合元素从倒序改为正序进行排序）
	 */
	public static <T> List<T> reverseList(List<T> list) {
		return Lists.reverse(list);
	}

	/**
	 * 把 list 用分隔符组装成一个字符串
	 */
	public static String listJoinToString(List<String> list, String separator) {
		return Joiner.on(separator).join(list);
	}

	/**
	 * 把一个可变列表改为不可变列表
	 */
	public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
		return ImmutableList.copyOf(elements);
	}

	/**
	 * 把 jdk 列表转换成 multiset，方便根据元素统计重复个数，可以用来做各种计数场景
	 *
	 * @Test public void test() {
	 * List<String> mylist = new ArrayList<>();
	 * mylist.add("11111111111111111");
	 * mylist.add("11111111111111111");
	 * mylist.add("11111111111111111");
	 * mylist.add("11111111111111112");
	 * mylist.add("11111111111111113");
	 * mylist.add("11111111111111114");
	 * <p>
	 * Multiset<String> multiset = CollectionUtil.listToMultiset(mylist);
	 * <p>
	 * multiset.add("11111111111111111");
	 * <p>
	 * System.out.println("------zch------" + multiset.size());
	 * System.out.println("------zch------" + multiset.count("11111111111111111"));
	 * System.out.println("------zch------" + multiset.count("11111111111111113"));
	 * // ------zch------7
	 * // ------zch------4
	 * // ------zch------1
	 * }
	 */
	public static <E> Multiset<E> listToMultiset(Collection<E> elements) {
		Multiset<E> multiset = HashMultiset.create();

		elements.stream().forEach(item -> {
			multiset.add(item);
		});

		return multiset;
	}

	/**
	 * 把 map 用分隔符组装成一个字符串
	 * 假如：
	 * map.put("John", 1000);
	 * map.put("Jane", 1500);
	 * 当 keyValueSeparator 为 =
	 * 当 elementSeparator 为 ,
	 * 结果：John=1000,Jane=1500
	 */
	public static String mapToString(Map map, String keyValueSeparator, String elementSeparator) {
		return Joiner.on(elementSeparator).withKeyValueSeparator(keyValueSeparator).join(map);
	}


	/**
	 * 把 string 转换为 map
	 * 比如格式：John=1000,Jane=1500
	 */
	public static Map stringToMap(String str, String keyValueSeparator, String elementSeparator) {
		return Splitter.on(elementSeparator).withKeyValueSeparator(keyValueSeparator).split(str);
	}

	public static <T> ArrayList<T> newList(T... elements) {
		return Lists.newArrayList(elements);
	}

	public static <T> HashSet<T> newSet(T... elements) {
		return Sets.newHashSet(elements);
	}
	// =====================================Guava 包 end=====================================

	// =====================================其他包 start=====================================

	public static <T> List<T> setToList(Set<T> set) {
		return new ArrayList<>(set);
	}

	public static <T> Set<T> listToSet(List<T> list) {
		return new HashSet<>(list);
	}

	/**
	 * 并集
	 */
	public static <T> List<T> union(List<T> list1, List<T> list2) {
		return new ArrayList<>(CollectionUtils.union(list1, list2));
	}

	/**
	 * 交集
	 */
	public static <T> List<T> intersection(List<T> list1, List<T> list2) {
		return new ArrayList<>(CollectionUtils.intersection(list1, list2));
	}

	/**
	 * 交集的补集（相对差集，也就是相同部分之外的不同内容）
	 */
	public static <T> List<T> disjunction(List<T> list1, List<T> list2) {
		return new ArrayList<>(CollectionUtils.disjunction(list1, list2));
	}

	/**
	 * set1 相对 set2 的差集、不同元素（前后参数位置有差别）
	 * 也就是取 set1 相对 set2 独有的元素
	 * 比如：set1：1，2，3，4
	 * 比如：set2：4，5，6
	 * 得到结果就是：1,2,3
	 */
	public static <T> Set<T> difference(Set<T> set1, Set<T> set2) {
		return Sets.difference(set1, set2);
	}

	/**
	 * 计算笛卡尔积（也就是两两组合的排列）
	 * 比如：set1(1,2,3,4)
	 * 比如：set2(4,5,6)
	 * 结果：[["1","4"],["1","5"],["1","6"],["2","4"],["2","5"],["2","6"],["3","4"],["3","5"],["3","6"],["4","4"],["4","5"],["4","6"]]
	 */
	public static <T> Set<List<T>> cartesianProduct(Set<T> set1, Set<T> set2) {
		return Sets.cartesianProduct(set1, set2);
	}

	/**
	 * 返回 set 集合中所有元素排列组合的可能性，包含第一个空集合
	 * 比如：Set(1,2,3,4) 得到的所有排列组合的可能性是：[[],["1"],["2"],["1","2"],["3"],["1","3"],["2","3"],["1","2","3"],["4"],["1","4"],["2","4"],["1","2","4"],["3","4"],["1","3","4"],["2","3","4"],["1","2","3","4"]]
	 */
	public static <T> Set<Set<T>> powerSet(Set<T> set) {
		return Sets.powerSet(set);
	}

	/**
	 * 去重
	 *
	 * @param list
	 */
	public static List<String> removeDuplicate(List<String> list) {
		LinkedHashSet<String> set = new LinkedHashSet<>(list.size());
		set.addAll(list);
		list.clear();
		list.addAll(set);
		return list;
	}

	// =====================================其他包 end=====================================


	// =====================================私有方法 start=====================================

	/**
	 * 数组转换成 List
	 */
	public static <T> List<T> toList(T[] arrays) {
		List<T> list = new ArrayList<>();
		CollectionUtils.addAll(list, arrays);
		return list;
	}

	/**
	 * List 转换成数组
	 * String[] strings = CollectionUtil.toArray(stringList, String.class);
	 */
	public static <T> T[] toArray(Collection<T> collection, Class<T> componentType) {
		final T[] array = newArray(componentType, collection.size());
		return collection.toArray(array);
	}

	/**
	 * 新建一个空数组
	 */
	@SuppressWarnings("unchecked")
	public static <T> T[] newArray(Class<?> componentType, int newSize) {
		return (T[]) Array.newInstance(componentType, newSize);
	}

	// =====================================私有方法 end=====================================

}



